package it.polito.let.jhp;

import it.polito.let.http.HTTPError;
import it.polito.let.http.Request;
import it.polito.let.http.Responder;
import it.polito.let.http.parser.HTTPCup;
import it.polito.let.http.parser.HTTPLex;
import it.polito.let.jhp.form.JHPForm;
import it.polito.let.jhp.types.TypeList;
import it.polito.let.jhp.types.Value;
import it.polito.let.util.LimitedInputStream;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.util.*;

public abstract class JHPResponder extends Responder {

	Request request;

	public JHPResponder() throws HTTPError {
		super();
	}

	public void setRequest (Request r) {
		request = r;
	}

	@Override
	public Request getRequest() {
		return request;
	}

	public abstract String formCallbacks(int id, Map<String, Value> POST);

	protected abstract List<Object> getDocument();

	protected void returnJHPDocument() throws HTTPError {
		List <Object> doc;
		switch (getRequest().getRequestType()) {
		case GET:
			doc = getDocument();
			break;
		case POST:
			int contentLength = Integer.parseInt(getRequest().getHeaderField("Content-Length").getToken()); 
			LimitedInputStream in = new LimitedInputStream(getRequest().getPayloadStream(),contentLength);
			HTTPCup parser = new HTTPCup(new HTTPLex(in));
			parser.setDocumentList(getDocument());
			parser.setResponder(this);
			try {	
				parser.parse();
			} catch (Exception e) {
				HTTPError he = new HTTPError((short) 500,"Server Error");
				he.addAdditionalInfo("Unable to parse user data: \r\nReason: " + e.getMessage());
				throw he;
			}
			if (parser.syntax_error != 0) { // Semantic error reporting is handled by the parser
				HTTPError he = new HTTPError((short) 500,"Server Error");
				he.addAdditionalInfo("Unable to parse user data: \r\nReason: " + parser.getErrorReport());
				throw he;
			}
			doc = parser.getDocumentList();
			break;
		default:
			throw new HTTPError((short) 501, "Not Implemented");
		}
		StringBuffer buf = new StringBuffer();
		for (Object s:doc) {
			if(s instanceof JHPForm){
				buf.append((((JHPForm)s).toString()));	
			} else {
				buf.append(s.toString());
			}
		}
		String s = buf.toString(); 
		ByteArrayInputStream FileBuf = new ByteArrayInputStream (s.getBytes()) ; 
		DataInputStream inData = new DataInputStream (FileBuf) ; 
		super.returnStream(inData);
	}

}
